2022_feldman_projection_ii.py

#

SPDX-FileCopyrightText: 2022 Sebastian Big SPDX-FileCopyrightText: 2024 AlICe laboratory https://alicelab.be

SPDX-License-Identifier: GPL-3.0-or-later

import bpy
import random
#

clean up

#
def clean():
    bpy.ops.object.select_all(action="SELECT")
    bpy.ops.object.delete(use_global=False)
    bpy.ops.outliner.orphans_purge()


clean()
#

creating function based on type of instrument: blowing, string and keys

#
def blowing(importance, position, dynamics):
    bpy.ops.mesh.primitive_cylinder_add(
        radius=importance / 4, location=(position), scale=(dynamics)
    )
    bpy.context.object.name = "blow"
#
def string(importance, position, dynamics):
    bpy.ops.mesh.primitive_cube_add(
        size=importance / 4, location=(position), scale=(dynamics)
    )
    bpy.context.object.name = "string"
#

entering edit mode to be abgle to divide the volume so it could be modified after

    bpy.ops.object.editmode_toggle()
    bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type="EDGE")
    bpy.ops.mesh.subdivide()
    bpy.ops.mesh.subdivide(number_cuts=20)
    bpy.ops.object.editmode_toggle()

    return bpy.context.object.name
#
def keys(importance, position, dynamics):
    bpy.ops.mesh.primitive_cylinder_add(
        radius=importance / 4, location=(position), scale=(dynamics)
    )
    bpy.context.object.name = "keys"
#

creating lists to be able to stock coordinate to be able to call it later

#
LIST FOR FLUTE
blow_flute1 = []
blow_flute2 = []
blow_flute3 = []
#

crreating the loop to be able to generate multiple volumes just by changing the y value

#

for ny in range(1,3):

loop

for ni in range(3):
#

creating é varaibles to be able to control the distance between them after

    x1 = random.uniform(0.5, 9.5)
    x2 = random.uniform(0.5, 9.5)
    y = -1.6
#

check distance between x1 and x2

    while abs(x1 - x2) < 2:
#

new x2 if too close

        x2 = random.uniform(0.5, 9.5)
#

make coordinates with x1 and x2

    for x in [x1, x2]:
#

y = -1.6*ny implementing the random y to each range

        if ni == 1:
            z = random.uniform(7, 10)
            blow_flute1.append([x, y, z])
        elif ni == 2:
            z = random.uniform(4, 7)
            blow_flute2.append([x, y, z])
        else:
            z = random.uniform(1, 4)
            blow_flute3.append([x, y, z])
#

create objects for coordinates

for coord in blow_flute1:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    blowing(2, (x, y, z / 2), (0.5, random.uniform(1, 2), z / 2))

print(len(blow_flute1))

for coord in blow_flute2:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    blowing(2, (x, y, z / 2), (0.5, random.uniform(1, 2), z / 2))

for coord in blow_flute3:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    blowing(2, (x, y, z / 2), (0.5, random.uniform(1, 2), z / 2))
#

from this moment, the code repeats itself, just by changing the list for each insstrument and the y value

#
LIST FOR TRUMPET
blow_trump1 = []
blow_trump2 = []
blow_trump3 = []
#

for ny in range(1,3):

loop

for ni in range(3):
    x1 = random.uniform(0.5, 9.5)
    x2 = random.uniform(0.5, 9.5)
    y = -1.6 * 2
#

check distance between x1 and x2

    while abs(x1 - x2) < 2:
#

new x2 if too close

        x2 = random.uniform(0.5, 9.5)
#

make coordinates with x1 and x2

    for x in [x1, x2]:
#

y = -1.6*ny

        if ni == 1:
            z = random.uniform(7, 10)
            blow_trump1.append([x, y, z])
        elif ni == 2:
            z = random.uniform(4, 7)
            blow_trump2.append([x, y, z])
        else:
            z = random.uniform(1, 4)
            blow_trump3.append([x, y, z])
#

create objects for coordinates

for coord in blow_trump1:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    blowing(2, (x, y, z / 2), (random.uniform(1, 2), 1, z / 2))

print(len(blow_flute1))

for coord in blow_trump2:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    blowing(2, (x, y, z / 2), (random.uniform(1, 2), 1, z / 2))

for coord in blow_trump3:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    blowing(2, (x, y, z / 2), (random.uniform(1, 2), 1, z / 2))


string_violin1 = []
string_violin2 = []
string_violin3 = []
#

for ny in range(1,3):

loop

for ni in range(3):
    x1 = random.uniform(0.5, 9.5)
    x2 = random.uniform(0.5, 9.5)
    y = -1.6 * 3
#

check distance between x1 and x2

    while abs(x1 - x2) < 2:
#

new x2 if too close

        x2 = random.uniform(0.5, 9.5)
#

make coordinates with x1 and x2

    for x in [x1, x2]:
#

y = -1.6*ny

        if ni == 1:
            z = random.uniform(7, 10)
            string_violin1.append([x, y, z])
        elif ni == 2:
            z = random.uniform(4, 7)
            string_violin2.append([x, y, z])
        else:
            z = random.uniform(1, 4)
            string_violin3.append([x, y, z])
#

create objects for coordinates

for coord in string_violin1:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    string(2, (x, y, z / 2), (random.uniform(1, 2), random.uniform(1, 2), z * 2))

print(len(blow_flute1))

for coord in string_violin2:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    string(2, (x, y, z / 2), (random.uniform(1, 2), random.uniform(1, 2), z * 2))

for coord in string_violin3:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    string(2, (x, y, z / 2), (random.uniform(1, 2), random.uniform(1, 2), z * 2))
#
LIST FOR CELLO
string_cello1 = []
string_cello2 = []
string_cello3 = []
#

CREATING THE LOOP

for ny in range(1,3):

for ni in range(3):
    x1 = random.uniform(0.5, 9.5)
    x2 = random.uniform(0.5, 9.5)
    y = -1.6 * 4
#

check distance between x1 and x2

    while abs(x1 - x2) < 2:
#

new x2 if too close

        x2 = random.uniform(0.5, 9.5)
#

make coordinates with x1 and x2

    for x in [x1, x2]:
#

y = -1.6*ny

        if ni == 1:
            z = random.uniform(7, 10)
            string_cello1.append([x, y, z])
        elif ni == 2:
            z = random.uniform(4, 7)
            string_cello2.append([x, y, z])
        else:
            z = random.uniform(1, 4)
            string_cello3.append([x, y, z])
#

create objects for coordinates

for coord in string_cello1:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    string(2, (x, y, z / 2), (random.uniform(1, 2), 1, z * 2))

print(len(string_cello1))

for coord in string_cello2:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    string(2, (x, y, z / 2), (random.uniform(1, 2), 1, z * 2))

for coord in string_cello3:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    string(2, (x, y, z / 2), (random.uniform(1, 2), 1, z * 2))
#
LIST FOR PIANO
keys_piano1 = []
keys_piano2 = []
keys_piano3 = []
#

for ny in range(1,3):

loop

for ni in range(3):
    x1 = random.uniform(0.5, 9.5)
    x2 = random.uniform(0.5, 9.5)
    y = -1.6 * 5
#

check distance between x1 and x2

    while abs(x1 - x2) < 2:
#

new x2 if too close

        x2 = random.uniform(0.5, 9.5)
#

make coordinates with x1 and x2

    for x in [x1, x2]:
#

y = -1.6*ny

        if ni == 1:
            z = random.uniform(7, 10)
            keys_piano1.append([x, y, z])
        elif ni == 2:
            z = random.uniform(4, 7)
            keys_piano2.append([x, y, z])
        else:
            z = random.uniform(1, 4)
            keys_piano3.append([x, y, z])
#

create objects for coordinates

for coord in keys_piano1:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    keys(random.uniform(1, 2), (x, y, z / 2), (1, 1, z / 2))

print(len(blow_flute1))

for coord in keys_piano2:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    keys(random.uniform(1, 2), (x, y, z / 2), (1, 1, z / 2))

for coord in keys_piano3:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    keys(random.uniform(1, 2), (x, y, z / 2), (1, 1, z / 2))
#

tried to create a list for the object to be able to apply a deform modifier on y axis to create different twist in the volumes taht were subdivised

#

obj_to_modify = []

deselect all

for obj in bpy.data.objects: if ‘string’ in obj.name: # and (‘keys’ in obj.name): obj_to_modify.append(obj) print(obj_to_modify) obj.select_set(True)

#

join

#

for obj in obj_to_modify: # apply modifier value = random.choice([90,180,270]) bpy.ops.object.modifier_add(type=’SIMPLE_DEFORM’) bpy.context.object.modifiers[“SimpleDeform”].deform_axis = ‘Z’ bpy.context.object.modifiers[“SimpleDeform”].angle = value

#

#value = random.choice([1,2,3]) #pass

#
LIST FOR PIANO
keys_piano4 = []
keys_piano5 = []
keys_piano6 = []
#

for ny in range(1,3):

loop

for ni in range(3):
    x1 = random.uniform(0.5, 9.5)
    x2 = random.uniform(0.5, 9.5)
    y = -1.6 * 6
#

check distance between x1 and x2

    while abs(x1 - x2) < 2:
#

new x2 if too close

        x2 = random.uniform(0.5, 9.5)
#

make coordinates with x1 and x2

    for x in [x1, x2]:
#

y = -1.6*ny

        if ni == 1:
            z = random.uniform(7, 10)
            keys_piano4.append([x, y, z])
        elif ni == 2:
            z = random.uniform(4, 7)
            keys_piano5.append([x, y, z])
        else:
            z = random.uniform(1, 4)
            keys_piano6.append([x, y, z])
#

create objects for coordinates

for coord in keys_piano4:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    keys(random.uniform(1, 2), (x, y, z / 2), (1, 1, z / 2))

for coord in keys_piano5:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    keys(random.uniform(1, 2), (x, y, z / 2), (1, 1, z / 2))

for coord in keys_piano6:
    x = coord[0]
    y = coord[1]
    z = coord[2]
    keys(random.uniform(1, 2), (x, y, z / 2), (1, 1, z / 2))
#

defining a function to create the vertices of the mesh by calling the coordinates from the list created

def create_mesh(coordinates):
#

make face from list of coordinates/vertices

    myVerticles = coordinates
#

myFaces = [tuple([i for i in range(len(coordinates))])]

    myMesh = bpy.data.meshes.new("Mesh")
    myObject = bpy.data.objects.new("Mesh", myMesh)

    myCollection = bpy.context.collection
    myCollection.objects.link(myObject)

    myMesh.from_pydata(myVerticles, [], [])
#

mesh for the high pitch

create_mesh(
    blow_flute1
    + blow_trump1
    + string_violin1
    + string_cello1
    + keys_piano1
    + keys_piano4
)
#

mesh for the middle pitch

create_mesh(
    blow_flute2
    + blow_trump2
    + string_violin2
    + string_cello2
    + keys_piano2
    + keys_piano5
)
#

mesh for the low pitch

create_mesh(
    blow_flute3
    + blow_trump3
    + string_violin3
    + string_cello3
    + keys_piano3
    + keys_piano6
)
#

to be abgle to create the faces, i had to create a loop to select the verticies for each mesh and create a face from those vertices by searching by their names

for obj in bpy.data.objects:
    if "Mesh.015" in obj.name:
        print(obj.name)
        obj.select_set(True)
        bpy.ops.object.editmode_toggle()
        bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type="VERT")
        bpy.ops.mesh.edge_face_add()
        bpy.ops.object.editmode_toggle()

for obj in bpy.data.objects:
    if "Mesh.016" in obj.name:
        print(obj.name)
        obj.select_set(True)
        bpy.ops.object.editmode_toggle()
        bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type="VERT")
        bpy.ops.mesh.edge_face_add()
        bpy.ops.object.editmode_toggle()

for obj in bpy.data.objects:
    if "Mesh.017" in obj.name:
        print(obj.name)
        obj.select_set(True)
        bpy.ops.object.editmode_toggle()
        bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type="VERT")
        bpy.ops.mesh.edge_face_add()
        bpy.ops.object.editmode_toggle()